package com.project.springboot.controller;

import com.gitee.yongzhuzl.commonutil.util.result.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.*;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * 说明：因为只是简单的测试一下Redisson，不涉及到关系型数据库操作，所以为了方便起见这里就不使用Service了
 * description: Redisson功能测试控制器
 * @author 朱正磊
 * @date 2025-06-27 11:11:18
 */
@Slf4j
@RestController
@RequestMapping("/redisson")
public class RedissonController {

    @Resource
    private RedissonClient redissonClient;

    /**
     * description: 测试可重入锁
     * @author 朱正磊
     * @date 2025-06-27 11:25:00
     * @return 返回响应对象
     */
    @PostMapping("/test1")
    public ResponseResult<Void> test1() {
        RLock rLock = redissonClient.getLock("my-lock");
        rLock.lock();
        try {
            // TODO: 2025/6/27 读数据
        } catch (Exception e) {
            // 其实可以没有catch，有try finally就行
            log.error("异常信息：", e);
            throw new RuntimeException(e);
        } finally {
            // 其实可以不需要显式调用rLock.isHeldByCurrentThread()进行判断
            if (rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        return ResponseResult.buildSuccess();
    }

    /**
     * description: 测试读写锁之读锁
     * @author 朱正磊
     * @date 2025-06-27 11:25:00
     * @return 返回响应对象
     */
    @PostMapping("/test2")
    public ResponseResult<Void> test2() {
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        RLock rLock = readWriteLock.readLock();
        rLock.lock();
        try {
            // TODO: 2025/6/27 读数据
        } catch (Exception e) {
            // 其实可以没有catch，有try finally就行
            log.error("异常信息：", e);
            throw new RuntimeException(e);
        } finally {
            // 其实可以不需要显式调用rLock.isHeldByCurrentThread()进行判断
            if (rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        return ResponseResult.buildSuccess();
    }

    /**
     * description: 测试读写锁之写锁
     * @author 朱正磊
     * @date 2025-06-27 11:25:00
     * @return 返回响应对象
     */
    @PostMapping("/test3")
    public ResponseResult<Void> test3() {
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        RLock rLock = readWriteLock.writeLock();
        rLock.lock();
        try {
            // TODO: 2025/6/27 写数据
        } catch (Exception e) {
            // 其实可以没有catch，有try finally就行
            log.error("异常信息：", e);
            throw new RuntimeException(e);
        } finally {
            // 其实可以不需要显式调用rLock.isHeldByCurrentThread()进行判断
            if (rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        return ResponseResult.buildSuccess();
    }

    /**
     * description: 测试信号量
     * @author 朱正磊
     * @date 2025-06-27 11:25:00
     * @return 返回响应对象
     */
    @PostMapping("/test4")
    public ResponseResult<String> test4() throws InterruptedException {
        RSemaphore park = redissonClient.getSemaphore("park");
        park.trySetPermits(10);

        // 获取一个信号、获取一个值，比如占一个车位
        park.acquire();
        boolean flag = park.tryAcquire();
        if (flag) {
            System.out.println("我抢到车位啦！");
        } else {
            return ResponseResult.buildError("停车失败！");
        }
        return ResponseResult.buildSuccess("停车成功！");
    }

    /**
     * description: 有车离开车位
     * @author 朱正磊
     * @date 2025-06-27 14:07:35
     * @return 返回响应对象
     */
    @GetMapping("/go")
    public ResponseResult<String> go() {
        RSemaphore park = redissonClient.getSemaphore("park");
        park.release();
        return ResponseResult.buildSuccess("释放一个车位！");
    }

    /**
     * description: 测试闭锁
     * @author 朱正磊
     * @date 2025-06-27 11:25:00
     * @return 返回响应对象
     */
    @PostMapping("/test5")
    public ResponseResult<String> test5() throws InterruptedException {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.trySetCount(5);
        door.await();
        return ResponseResult.buildSuccess("放假了，所有学生已全部离开学校，锁大门！");
    }

    /**
     * description: 教室学生放学回家
     * @author 朱正磊
     * @date 2025-06-27 13:12:02
     * @param classId 班级ID
     * @return 返回响应对象
     */
    @GetMapping("/goAway/{classId}")
    public ResponseResult<String> goAway(@PathVariable("classId") String classId) {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.countDown();
        return ResponseResult.buildSuccess(classId + "班的人都走了......");
    }

}
